package com.example.demo.utils;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.HeaderFooter;
import com.spire.doc.Section;
import com.spire.doc.documents.Paragraph;
import com.spire.doc.documents.ShapeLineStyle;
import com.spire.doc.documents.ShapeType;
import com.spire.doc.fields.ShapeObject;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.*;

public class OfficeWaterMarkUtil {

    /**
     * word文字水印
     *
     * @param inputPath
     * @param outPath
     * @param markStr
     */
    public static void addWordWaterMark(String inputPath, String outPath, String markStr) {
        //加载示例文档
        Document doc = new Document();
        doc.loadFromFile(inputPath);
        //添加艺术字并设置大小
        ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text);
        shape.setWidth(80);
        shape.setHeight(20);
        //设置艺术字文本内容、位置及样式
        shape.setVerticalPosition(30);
        shape.setHorizontalPosition(20);
        shape.setRotation(315);
        shape.getWordArt().setFontFamily("宋体");
        shape.getWordArt().setText(markStr);
        shape.setFillColor(Color.red);
        shape.setLineStyle(ShapeLineStyle.Single);
        shape.setStrokeColor(new Color(192, 192, 192, 255));
        shape.setStrokeWeight(1);

        Section section;
        HeaderFooter header;
        for (int n = 0; n < doc.getSections().getCount(); n++) {
            section = doc.getSections().get(n);
            //获取section的页眉
            header = section.getHeadersFooters().getHeader();
            Paragraph paragraph;

            if (header.getParagraphs().getCount() > 0) {
                //如果页眉有段落，取它第一个段落
                paragraph = header.getParagraphs().get(0);
            } else {
                //否则新增加一个段落到页眉
                paragraph = header.addParagraph();
            }
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 3; j++) {
                    //复制艺术字并设置多行多列位置
                    shape = (ShapeObject) shape.deepClone();
                    shape.setVerticalPosition(50 + 150 * i);
                    shape.setHorizontalPosition(20 + 160 * j);
                    paragraph.getChildObjects().add(shape);
                }
            }
        }
        //保存文档
        doc.saveToFile(outPath, FileFormat.Docx_2013);
    }

    /**
     *pdf文件添加文字水印
     *
     * @param input         原PDF位置
     * @param output        输出文件的位置
     * @param waterMarkName 页脚添加水印
     */
    public static void addPDFWaterMark(String input, String output, String waterMarkName) {
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(new File(output)));
            PdfReader reader = new PdfReader(input);
            PdfStamper stamper = new PdfStamper(reader, bos);

            // 获取总页数 +1, 下面从1开始遍历
            int total = reader.getNumberOfPages() + 1;
            // 使用classpath下面的字体库
            com.itextpdf.text.pdf.BaseFont base = null;
            try {
                base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", com.itextpdf.text.pdf.BaseFont.EMBEDDED);
            } catch (Exception e) {
                // 日志处理
                e.printStackTrace();
            }

            // 间隔
            int interval = -15;
            // 获取水印文字的高度和宽度
            int textH = 0, textW = 0;
            JLabel label = new JLabel();
            label.setText(waterMarkName);
            FontMetrics metrics = label.getFontMetrics(label.getFont());
            textH = metrics.getHeight();
            textW = metrics.stringWidth(label.getText());
            System.out.println("textH: " + textH);
            System.out.println("textW: " + textW);

            // 设置水印透明度
            com.itextpdf.text.pdf.PdfGState gs = new com.itextpdf.text.pdf.PdfGState();
            gs.setFillOpacity(0.2f);
            gs.setStrokeOpacity(0.7f);

            com.itextpdf.text.Rectangle pageSizeWithRotation = null;
            PdfContentByte content = null;
            for (int i = 1; i < total; i++) {
                // 在内容上方加水印
                content = stamper.getOverContent(i);
                // 在内容下方加水印
                // content = stamper.getUnderContent(i);
                content.saveState();
                content.setGState(gs);

                // 设置字体和字体大小
                content.beginText();
                content.setFontAndSize(base, 20);

                // 获取每一页的高度、宽度
                pageSizeWithRotation = reader.getPageSizeWithRotation(i);
                float pageHeight = pageSizeWithRotation.getHeight();
                float pageWidth = pageSizeWithRotation.getWidth();

                // 根据纸张大小多次添加， 水印文字成30度角倾斜
                for (int height = interval + textH; height < pageHeight; height = height + textH * 6) {
                    for (int width = interval + textW; width < pageWidth + textW; width = width + textW * 2) {
                        content.showTextAligned(Element.ALIGN_LEFT, waterMarkName, width - textW, height - textH, 30);
                    }
                }

                content.endText();
            }

            // 关流
            stamper.close();
            reader.close();
        } catch (FileNotFoundException e) {
            throw new RuntimeException("PDF makewater fail：生成ppt文件失败");
        } catch (DocumentException e) {
            throw new RuntimeException("PDF makewater fail：生成ppt文件失败");
        } catch (IOException e) {
            throw new RuntimeException("PDF makewater fail：生成ppt文件失败");
        }

    }


    /**
     *
     * @param wb   Excel Workbook
     * @param sheet  需要打水印的Excel
     * @param waterRemark  水印文字
     * @param startXCol   水印起始列
     * @param startYRow  水印起始行
     * @param betweenXCol  水印横向之间间隔多少列
     * @param betweenYRow  水印纵向之间间隔多少行
     * @param XCount    横向共有水印多少个
     * @param YCount    纵向共有水印多少个
     * @param waterRemarkWidth   水印图片宽度为多少列
     * @param waterRemarkHeight   水印图片高度为多少行
     * @throws IOException
     */
    public static void putWaterRemarkToExcel(Workbook wb, Sheet sheet, String waterRemark, int startXCol,
                                             int startYRow, int betweenXCol, int betweenYRow, int XCount, int YCount, int waterRemarkWidth,
                                             int waterRemarkHeight) throws IOException {
        // 加载图片
        ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
        BufferedImage bufferImg = createWaterMarkImage(waterRemark);
        ImageIO.write(bufferImg, "png", byteArrayOut);
        // 开始打水印
        Drawing drawing = sheet.createDrawingPatriarch();
        Drawing<?> drawingPatriarch = sheet.getDrawingPatriarch();
        // 按照共需打印多少行水印进行循环
        for (int yCount = 0; yCount < YCount; yCount++) {
            // 按照每行需要打印多少个水印进行循环
            for (int xCount = 0; xCount < XCount; xCount++) {
                // 创建水印图片位置
                int xIndexInteger = startXCol + (xCount * waterRemarkWidth) + (xCount * betweenXCol);
                int yIndexInteger = startYRow + (yCount * waterRemarkHeight) + (yCount * betweenYRow);
                /*
                 * 参数定义： 第一个参数是（x轴的开始节点）； 第二个参数是（是y轴的开始节点）； 第三个参数是（是x轴的结束节点）；
                 * 第四个参数是（是y轴的结束节点）； 第五个参数是（是从Excel的第几列开始插入图片，从0开始计数）；
                 * 第六个参数是（是从excel的第几行开始插入图片，从0开始计数）； 第七个参数是（图片宽度，共多少列）；
                 * 第8个参数是（图片高度，共多少行）；
                 */
                ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, xIndexInteger,
                        yIndexInteger, xIndexInteger + waterRemarkWidth, yIndexInteger + waterRemarkHeight);

                Picture pic = drawing.createPicture(anchor,
                        wb.addPicture(byteArrayOut.toByteArray(), Workbook.PICTURE_TYPE_PNG));
                pic.resize();
            }
        }
    }

    /**
     * excel文件添加文字水印
     *
     * @param inputSrc      原excel位置
     * @param outputSrc     输出文件的位置
     * @param waterMarkName 页脚添加水印
     */
    public static void setExcelWaterMark(String inputSrc, String outputSrc, String waterMarkName){
        try {
            //读取excel文件
            Workbook wb =null;
            if (inputSrc.endsWith("xls")) {
                wb = new HSSFWorkbook(new FileInputStream(inputSrc));
            }else if (inputSrc.endsWith("xlsx")){
                wb = new XSSFWorkbook(new FileInputStream(inputSrc));
            }
            //获取excel sheet个数
            int sheets = wb.getNumberOfSheets();
            //循环sheet给每个sheet添加水印
            for (int i = 0; i < sheets; i++) {
                Sheet sheet = wb.getSheetAt(i);
                //获取excel实际所占行
                int row = sheet.getFirstRowNum() + sheet.getLastRowNum();
                //获取excel实际所占列
                Row row1 = sheet.getRow(sheet.getFirstRowNum());
                if (row1==null){
                    continue;
                }
                int cell = sheet.getRow(sheet.getFirstRowNum()).getLastCellNum() + 1;
                //根据行与列计算实际所需多少水印
                putWaterRemarkToExcel(wb, sheet, waterMarkName, 0, 0, 6, 8, cell / 6 + 1, row / 8 + 1, 0, 0);

                //设置为受保护
                sheet.protectSheet(waterMarkName);
            }
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            try {
                wb.write(os);
            } catch (IOException e) {
                e.printStackTrace();
            }
            wb.close();
            byte[] content = os.toByteArray();
            // Excel文件生成后存储的位置。
            File file1 = new File(outputSrc);
            OutputStream fos = null;
            try {
                fos = new FileOutputStream(file1);
                fos.write(content);
                os.close();
                fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public static BufferedImage createWaterMarkImage(String waterMark) {
        String[] textArray = waterMark.split("\n");
        Font font = new Font("microsoft-yahei", Font.PLAIN, 20);
        Integer width = 500;
        Integer height = 200;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        // 背景透明 开始
        Graphics2D g = image.createGraphics();
        image = g.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        g.dispose();
        // 背景透明 结束
        g = image.createGraphics();
        g.setColor(new Color(Integer.parseInt("#C5CBCF".substring(1), 16)));// 设定画笔颜色
        g.setFont(font);// 设置画笔字体
        g.shear(0.1, -0.26);// 设定倾斜度
        // 设置字体平滑
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        int y = 150;
        for (int i = 0; i < textArray.length; i++) {
            g.drawString(textArray[i], 0, y);// 画出字符串
            y = y + font.getSize();
        }
        g.dispose();// 释放画笔
        return image;
    }



}
